<template>
  <view class="container">
    <view class="search-button" @click="viewSearchHistory">
      <text class="search-icon">🔍搜题记录</text>
    </view>
    <!-- 初始拍照按钮 -->
    <view v-if="!selectedImagePath" class="photo-button-wrapper">
      <image
        class="photo-button"
        src="/static/search.png"
        @click="chooseImage"
      />
    </view>

    <!-- 拍照后显示的大框 -->
    <view v-if="selectedImagePath" class="image-preview message-bubble">
      <!-- 预览图片放在最上面 -->
      <image class="preview-image" :src="selectedImagePath" />

      <!-- 解题文本 -->
      <view class="solution-text">
        <scroll-view class="scroll-box" scroll-y>
          <span>解题结果：</span>
          <view class="message-bubble">
            <!--          <MarkdownViewer :markdown="solutionText"></MarkdownViewer>-->
            <text>{{ solutionText }}</text>
          </view>
        </scroll-view>
      </view>

      <!-- 继续拍照提示 -->
      <view class="upload-paper-button" @click="handleReTake">
        <text>再拍一张</text>
      </view>
    </view>
  </view>
</template>

<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
  name: "Search",
  data() {
    return {
      chatId: 'cs6dk1tvfrpprqp73380',
      fileName: "",
      selectedImagePath: "",
      solutionText: "",
    };
  }, created() {
    const chatid = uni.getStorageSync('chatId');
    if (chatid) {
      this.chatId = chatid;
    }
  },
  onHide() {
    const chatid = uni.getStorageSync('chatId');
    if (chatid) {
      this.chatId = chatid;
    }
  },
  methods: {
    refreshUserToken() {
      const refreshToken = uni.getStorageSync("refresh_token");
      uni.request({
        method: "GET",
        url: "https://kimi.moonshot.cn/api/auth/token/refresh",
        header: {
          "Content-Type": "application/json",
          Authorization: `Bearer ${refreshToken}`,
        },
        success: (res) => {
          if (res.statusCode == 200) {
            const token = res.data.access_token;
            const refreshToken = res.data.refresh_token;
            uni.setStorageSync("access_token", this.token);
            uni.setStorageSync("refresh_token", this.refreshToken);
          } else {
            uni.showToast({
              title: "登录过期,请重新登录",
              icon: "none",
            });
            uni.redirectTo({ url: "/pages/login/login" });
          }
        },
        fail: (fail) => {
          uni.showToast({
            title: "登录过期,请重新登录",
            icon: "none",
          });
          uni.redirectTo({ url: "/pages/login/login" });
        },
      });
    },
    async getsolutionText(id: string) {
      const token = uni.getStorageSync("access_token");
      const data = {
        messages: [{ role: "user", content: "这是一些试题，根据图片的内容，分析并按要求解答这些问题" }],
        use_search: false,
        extend: { sidebar: true },
        kimiplus_id: "kimi",
        use_research: false,
        refs: [id],
      };
      const requestTask = await uni.request({
        url: `https://kimi.moonshot.cn/api/chat/${this.chatId}/completion/stream`,
        method: "POST",
        header: {
          "Content-Type": "application/json",
          Authorization: `Bearer ${token}`,
        },
        data: data,
        responseType: "text",
        enableChunked: true, // 启用分块接收
        success: (response) => {
          console.log("6 solution", response);
          if (response.statusCode == 404) {
            uni.redirectTo({ url: "/pages/login/login" });
          } else if (response.statusCode != 200) {
            this.refreshUserToken();
            this.preSignUrlFile(this.selectedImagePath, this.fileName);
          }
        },
        fail: (error) => {
          console.error("Failed to send message:", error);
        },
        complete: (com) => { },
      });

      requestTask.onHeadersReceived((res) => {
        console.log("header:", res);
      });

      requestTask.onChunkReceived((res) => {
        const uint8Array = new Uint8Array(res.data);
        let text = String.fromCharCode.apply(null, uint8Array);
        text = decodeURIComponent(escape(text));
        // 解析接收到的数据块
        this.processChunk(text);
      });
    },

    processChunk(chunkData) {
      const lines = chunkData.split("\n");

      lines.forEach((line) => {
        if (line.trim()) {
          try {
            const jsonObj = JSON.parse(line.substring(6)); // 移除 "data:" 前缀
            const { text, content, error, event } = jsonObj;

            if (event == "cmpl" && text) {
              this.solutionText += text; // 追加到当前文本
            } else if (error) {
              const { message } = error;

              this.solutionText += message; // 追加到当前文本
            } else if (event == "all_done") {
              console.log("all_done:", this.solutionText);
            } else {
            }
          } catch (error) {
            console.error("Error parsing JSON:", error);
          }
        }
      });
    },
    viewSearchHistory() {
      const token = uni.getStorageSync("access_token");
      if (!token) {
        uni.redirectTo({ url: "/pages/login/login" });
      } else {
        console.log("go history view");
        uni.redirectTo({ url: "/pages/history/history" });
      }
    },
    async chooseImage() {
      console.log('chooseImage')
      let _this = this;
      await uni.authorize({
        scope: "scope.camera",
        success() {
          _this.selectImage();
        },
        fail(err) {
                    // 用户拒绝授权，引导用户去设置中开启权限
            uni.showModal({
            title: '提示',
            content: '需要您授权访问相册，才能正常使用选择图片功能',
            success: modalRes => {
              if (modalRes.confirm) {
                // 用户点击确定，引导用户去设置页
                uni.openSetting({
                  success(settingdata) {
                    if (settingdata.authSetting['scope.writePhotosAlbum']) {
                      // 用户在设置页授权成功，可以再次调用选择图片接口
                      _this.chooseImage();
                    } else {
                      // 用户在设置页没有授权，可以给出提示
                      uni.showToast({
                        title: '需要授权才能使用',
                        icon: 'none',
                        duration: 2000
                      });
                    }
                  }
                });
              }
            }
          });
        },
      });
    },
    selectImage(){
      uni.chooseImage({
            count: 1,
            sizeType: ["original"],
            sourceType: ["album", "camera"],
            success: (res) => {
              if (res.errMsg == "chooseImage:ok") {
                const tempFilePaths = res.tempFilePaths;
                const fileIndex = tempFilePaths.length - 1;
                const tempFilePath = tempFilePaths[fileIndex];
                this.selectedImagePath = tempFilePath;
                this.preSignUrlFile(tempFilePath);
            
              } else {
                uni.showToast({ title: "请重新操作", icon: "none" });
              }
            },
            fail: (err) => {
              console.error("选择图片失败：", err);
            },
          });
    }
    ,

    uploadFile(fileName: string, filePath: string, url: string, object_name: string) {
      let _this = this;
      // 读取文件内容
      uni.getFileSystemManager().readFile({
        filePath: filePath,
        success: function (res) {
          // 构建请求体，这里以二进制数据为例
          const fileData = res.data;

          // 可以在这里将文件数据转换为Base64等格式，根据后端需求

          // 设置请求头
          const header = {
            'Content-Type': 'application/octet-stream',
            'origin': 'https://kimi.moonshot.cn'
            // 其他需要的头部信息
          };

          // 发送PUT请求
          uni.request({
            url: url, // 上传API的URL
            method: 'PUT',
            data: fileData,
            header: header,
            success: function (uploadRes) {
              console.log('上传成功:', uploadRes.data);
              _this.uploadTextFile(fileName, object_name);
            },
            fail: function (error) {
              console.error('上传失败:', error);
            }
          });
        }
      });
    }
    ,
    async parseProcessFile(id: string, presigned_url: string) {

      const access_token = uni.getStorageSync("access_token");

      const params = { ids: [id] };

      console.log(params)
      await uni.request({
        url: "https://kimi.moonshot.cn/api/file/parse_process",
        method: "POST",
        header: {
          "Content-Type": "application/json",
          Authorization: `Bearer ${access_token}`,
        },
        data: params,
        responseType: "text",
        success: (res) => {
          // data: {"event":"resp","file_info":{"id":"cs51osojdo7ntj6uul3g","name":"音标.txt","highlight_name":"","type":"file","content_type":"txt","status":"parsed","size":523,"token_size":184,"failed_reason":""},"id":"cs51osojdo7ntj6uul3g","status":"parsed"}
          console.log("parse:", res);
          if (res.statusCode == 200) {
            console.log("4 parse:", id);
            this.getsolutionText(id);
          }
        },
      });
      console.log('presigned_url', presigned_url)
      uni.request({
        url: presigned_url,
        method: 'GET',
        header: {
          "Content-Type": "application/json",
          'accept': 'image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8',
        },
        success: (res) => {
          console.log('presigned_url size,', res)
        },
      });

      const param = { "refs": [id], "content": "" };
      uni.request({
        url: `https://kimi.moonshot.cn/api/chat/${this.chatId}/token_size`,
        method: 'POST',
        data: param,
        header: {
          "Content-Type": "application/json",
          Authorization: `Bearer ${access_token}`,
        },
        success: (res) => {
          console.log('token size,', res)
        },
      })
    },
    async presignedUrl(presigned_url: string, id: string) {
      await uni.request({
        url: presigned_url,
        method: "GET",
        success: ({ data, statusCode, header }) => {
          this.parseProcessFile(id);
        },
        fail: (error) => { },
      });
    },
    async uploadFileToServer(
      tempFilePath: string
    ) {


      const fileName = tempFilePath.slice(tempFilePath.lastIndexOf("/") + 1);
      const token = uni.getStorageSync('access_token');
      let _this = this;
      await uni.uploadFile({
        url: 'http://localhost:8080/app/upload',
        filePath: tempFilePath,
        name: 'file',
        formData: { chatId: _this.chatId },
        header: { Authorization: `Bearer ${token}` },
        success(res) {
          console.log('resfile:', res)
          _this.parseProcessFile(JSON.parse(res.data).id, JSON.parse(res.data).presigned_url)
        }
      })
    },
    async uploadTextFile(fileName: string, objectName: string) {
      const chatId = uni.getStorageSync("chatId");
      console.log("3file:", chatId);

      const access_token = uni.getStorageSync("access_token");
      const params = {
        type: "file",
        name: fileName,
        object_name: objectName,
        chat_id: chatId,
      };
      await uni.request({
        url: "https://kimi.moonshot.cn/api/file",
        method: "POST",
        data: params,
        header: {
          "Content-Type": "application/json",
          Authorization: `Bearer ${access_token}`,
        },
        success: (res) => {
          if (res.statusCode == 200) {
            console.log("3 file res:", res);
            this.presignedUrl(res.data.presigned_url, res.data.id);
          }
        },
      });
    },
    async preSignUrlFile(tempFilePath: string) {
      const token = uni.getStorageSync("access_token");
      if (!token) {
        this.refreshUserToken();
      }
      const fileName = tempFilePath.slice(tempFilePath.lastIndexOf("/") + 1);

      await uni.request({
        url: "https://kimi.moonshot.cn/api/pre-sign-url", // 你的上传接口地址
        method: "POST",
        data: {
          name: fileName,
          action: "file",
        },
        header: {
          "Content-Type": "application/json",
          Authorization: `Bearer ${token}`,
        },
        success: (res) => {
          if (res.statusCode == 200) {
            console.log("res:", res);

            this.uploadFile(fileName, tempFilePath, res.data.url, res.data.object_name);
            // this.uploadFileToServer(
            //   res.data.url,
            //   tempFilePath,
            //   res.data.object_name
            // );
          } else {
            this.refreshUserToken();
          }
        },
        fail: (error) => {
          console.error("上传失败", error);
        },
        complete: () => { },
      });
    },
    handleReTake() {
      this.chooseImage();
    },
  },
});
</script>
 
<style scoped>
.container {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  height: 100vh;
  background-color: #ffffff;
  /* 设置背景颜色为白色 */
}

.search-button {
  position: absolute;
  top: 10px;
  /* 与顶部的距离 */
  right: 10px;
  /* 与右侧的距离 */
  padding: 10px;
  background-color: transparent;
  /* 无背景色 */
  border: none;
  /* 无边框 */
  cursor: pointer;
  /* 鼠标悬停时显示指针 */
  display: flex;
  align-items: center;
  justify-content: center;
}

.search-icon {
  font-size: 24px;
  color: #007bff;
  /* 设置图标颜色 */
  background-color: #ffffff;
  /* 设置背景颜色 */
  border-radius: 50%;
  /* 设置圆形效果 */
  padding: 5px;
  /* 设置内边距 */
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  /* 设置阴影 */
}

.photo-button-wrapper {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 50vw;
  height: 50vw;
  border-radius: 50%;
  background-color: #fff;
  /* 保持内部背景为白色 */
  overflow: hidden;
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
}

.photo-button {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.image-preview {
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  align-items: center;
  width: 90%;
  height: 100vh;
  background-color: rgba(0, 0, 0, 0.8);
  /* 确保预览部分有深色背景 */
  position: fixed;
  top: 0;
  left: 0;
}

.preview-image {
  max-width: 90%;
  max-height: auto;
  /* 限制图片高度 */
}

.solution-text {
  margin-top: 20px;
  color: white;
  font-size: 18px;
  max-height: 40%;
}

.scroll-box {
  max-height: auto;
  overflow-y: auto;
  padding: 10px;
  background-color: rgba(0, 0, 0, 0.6);
}

.upload-paper-button {
  position: absolute;
  bottom: 5px;
  left: 20px;
  background-color: #007bff;
  color: #fff;
  border-radius: 10px;
  padding: 5px 10px;
}

.loading-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  background-color: rgba(0, 0, 0, 0.5);
  justify-content: center;
  align-items: center;
  display: flex;
  color: white;
  font-size: 20px;
}
</style>